﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	Entity.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Diagnostics;
using Smart.Common.Security;

namespace Smart.Common.Entities
{
	/// <summary>
	/// Entity base
	/// </summary>
	[Serializable]
	[Entity(Const.EntityNames.Entity)]
	[DebuggerDisplay("Entity {ID}: {Title}")]
	[DebuggerStepThrough]
	public class Entity : IEntity
	{
		/// <summary>
		/// Securable type
		/// </summary>
		public virtual SecurableType SecurableType
		{
			get { return null; }
		}

		/// <summary>
		/// Source list, where entity is saved
		/// </summary>
		public IEntityList List { get; set; }

		/// <summary>
		/// Datasource item
		/// </summary>
		public object Source { get; set; }

		/// <summary>
		/// Synchronization object (used to lock)
		/// </summary>
		[NonSerialized]
		public object SyncObj = new object();

		/// <summary>
		/// true, if fields changed
		/// </summary>
		public bool Changed { get; set; }

		/// <summary>
		/// Item ID
		/// </summary>
		[Field("ID", Direction = FieldMappingDirection.In)]
		public Identifier ID { get; set; }

		/// <summary>
		/// Item Title
		/// </summary>
		[Field("Title")]
		public string Title { get; set; }

		/// <summary>
		/// Return whether this entity is new
		/// </summary>
		public bool IsNew { get; set; }

		/// <summary>
		/// Event handler
		/// </summary>
		public virtual void OnCreated()
		{
		}

		/// <summary>
		/// Event handler, data source is in Source
		/// </summary>
		public virtual void OnLoading()
		{
		}

		/// <summary>
		/// Event handler, data source is in Source
		/// </summary>
		public virtual void OnLoaded()
		{
			lock (SyncObj)
			{
				Changed = false;
			}
		}

		/// <summary>
		/// Event handler, data source is in Source
		/// </summary>
		public virtual void OnSaving()
		{
		}

		/// <summary>
		/// Event handler, data source is in Source
		/// </summary>
		public virtual void OnSaved()
		{
			lock (SyncObj)
			{
				Changed = false;
			}
		}

		/// <summary>
		/// Reload all properties from source (uses ISPEntityList)
		/// </summary>
		public virtual bool Reload()
		{
			return List.Reload(this);
		}

		/// <summary>
		/// Save all properties to underlying system (uses ISPEntityList)
		/// </summary>
		/// <returns>true, if succeeded</returns>
		public virtual bool Save()
		{
			return List.Save(this);
		}

		/// <summary>
		/// Recycle item: move to recycle bin (uses ISPEntityList)
		/// </summary>
		/// <returns>true, if succeeded</returns>
		public virtual bool Recycle()
		{
			return List.Recycle(this);
		}

		/// <summary>
		/// Return item source
		/// </summary>
		public virtual object GetSource()
		{
			return Source ?? (Source = List.LoadSource(this));
		}

		/// <summary>
		/// Clone object using MemberwiseClone
		/// </summary>
		/// <returns>Cloned object (with the same instances of values)</returns>
		public object Clone()
		{
			var clone = (Entity)MemberwiseClone();

			clone.Source = null;
			clone.SyncObj = new object();

			return clone;
		}
	}
}